package com.googlecode.flex_solder.controls  {
  /**
   * $Id: DurationTimeCombo.as 29 2009-05-30 13:12:19Z fuller.sethm $
   * $URL$
   *
   * Author: Seth M. Fuller 
   * Copyright: 2008 
   * 
   *  This class extends the TimeCombo class, but does not use the
   *  timeValue Date property of that class. Instead to get the value
   *  represented by the dropdowns you can either get the durationSecs
   *  or durationMilliSecs properties from a DurationTimeCombo object.
   *
   *  If the user hasn't made a selection in the DurationTimeCombo
   *  ComboBox controls, the value of durationSecs and
   *  durationMilliSecs will be NaN (Not-a-Number), and the value of
   *  hour and minute will be -1. If the user has selected a duration
   *  time, then durationSecs will be set to the number of seconds
   *  that duration time represents and durationMilliSecs will be set
   *  to the number of milliseconds that duration time represents. The
   *  hour, minute, and second properties will set to the values
   *  displayed in the DurationTimeCombo when you get either the
   *  durationSecs or durationMilliSecs properties.
   *
   *  Permission is hereby granted, free of charge, to any person
   *  obtaining a copy of this software and associated documentation
   *  files (the "Software"), to deal in the Software without
   *  restriction, including without limitation the rights to use,
   *  copy, modify, merge, publish, distribute, sublicense, and/or
   *  sell copies of the Software, and to permit persons to whom the
   *  Software is furnished to do so, subject to the following
   *  conditions:
   *
   *  The above copyright notice and this permission notice shall be
   *  included in all copies or substantial portions of the Software.
   *
   *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
   *  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
   *  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
   *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   *  OTHER DEALINGS IN THE SOFTWARE.
   *
   * This file is licensed under the BSD (revised) open source
   * license.
   *
   * This is part of the flex-solder components hosted at
   * flex-solder.googlecode.com.
   *
   *======================================================================
   *
   * Contains third-party source code released with the same license terms
   * that appear above with the following copyright notice:
   *
   * Copyright (c) 2008 Yahoo! Inc.  All rights reserved.  The copyrights
   * embodied in the content of this file are licensed under the BSD
   * (revised) open source license
   *
   */
  import mx.controls.ComboBox;

  import mx.events.ListEvent;
  import com.googlecode.flex_solder.controls.TimeCombo;

  /**
   * @file   DurationTimeCombo.as
   * @author Seth Fuller <sethfuller@Sauron.home>
   * @date   Wed Dec 31 21:47:15 2008
   * 
   * @brief  The DurationTimeCombo implements a multiple-combo control
   * for measuring time durations, as opposed to clock time.
   * 
   */
  public class DurationTimeCombo extends TimeCombo {
    public static const SECONDS_PER_MINUTE:Number = 60;
    public static const MINUTES_PER_HOUR:Number = 60;
    public static const MILLISECS_PER_SECOND:Number = 1000;

    private var _durationSecs:Number;
    private var _durationMilliSecs:Number;

    public function DurationTimeCombo() {
      this.setStyle("useTwelveHourFormat", false);
      this.setStyle("showSeconds", false);
      this.setStyle("showAMPM", false);


    }

    protected function getDurationTimeComboValues():Number {

      var showSeconds:Boolean = this.getStyle("showSeconds");

      _durationSecs = 0;
      _durationMilliSecs = 0;
      _hour = -1;
      _minute = -1;
      _second = 0;

      if (null != hoursCombo && hoursCombo.selectedIndex >= 0) {
	_hour = hoursCombo.selectedItem as int;
      }

      if (null != minutesCombo && minutesCombo.selectedIndex >= 0) {
	_minute = minutesCombo.selectedItem as int;
      }

      if (showSeconds && null != secondsCombo
	  && secondsCombo.selectedIndex >= 0) {
	_second = secondsCombo.selectedItem as int;
      }


      _durationSecs = _hour * (DurationTimeCombo.MINUTES_PER_HOUR 
			      * DurationTimeCombo.SECONDS_PER_MINUTE);

      _durationSecs += _minute * DurationTimeCombo.SECONDS_PER_MINUTE;

      _durationSecs += _second;

      _durationMilliSecs
	= _durationSecs * DurationTimeCombo.MILLISECS_PER_SECOND;

      return _durationMilliSecs;

    }

    protected function setDurationTimeComboValues():void {
      var totalMinutes:uint;
      var totalSeconds:uint;

      _hour = -1;
      _minute = -1;
      _second = 0;

      totalMinutes = _durationMilliSecs 
	/ (DurationTimeCombo.SECONDS_PER_MINUTE 
	   * DurationTimeCombo.MILLISECS_PER_SECOND);

      totalSeconds = _durationMilliSecs 
	/ DurationTimeCombo.MILLISECS_PER_SECOND;

      _hour = int(totalMinutes / DurationTimeCombo.MINUTES_PER_HOUR);
//       trace("_durationMilliSecs=" + _durationMilliSecs);
//       trace("totalMinutes=" + totalMinutes);
//       trace("_hour=" + _hour);

      if (null != hoursCombo) {
	hoursCombo.selectedItem = _hour;
	hoursCombo.removeEventListener(ListEvent.CHANGE,  durationTimeComboChangeListener);
	hoursCombo.addEventListener(ListEvent.CHANGE,  durationTimeComboChangeListener);
      }

      if (null != minutesCombo) {

	_minute = int(totalMinutes % DurationTimeCombo.MINUTES_PER_HOUR);
	trace("_minute=" + _minute);
	minutesCombo.selectedItem = _minute;
	minutesCombo.removeEventListener(ListEvent.CHANGE,  durationTimeComboChangeListener);
	minutesCombo.addEventListener(ListEvent.CHANGE,  durationTimeComboChangeListener);
      }

      if (null != secondsCombo) {

	_second = int(totalSeconds % DurationTimeCombo.SECONDS_PER_MINUTE);
	secondsCombo.removeEventListener(ListEvent.CHANGE,  durationTimeComboChangeListener);
	secondsCombo.addEventListener(ListEvent.CHANGE,  durationTimeComboChangeListener);

	secondsCombo.selectedItem = _second;
      }

      //       dumpComboValues("setDurationTimeComboValues", hour, minute, second);
    }

    protected function durationTimeComboChangeListener(event:ListEvent):void {
	this.dispatchEvent(new Event(Event.CHANGE));
    }

    public function get durationMilliSecs():Number {
      _durationMilliSecs = getDurationTimeComboValues();
      return _durationMilliSecs;
    }

    [Bindable]
      public function set durationMilliSecs(durationMilliSecs:Number):void {
      _durationMilliSecs = durationMilliSecs;
      _durationSecs
	= _durationMilliSecs / DurationTimeCombo.MILLISECS_PER_SECOND;

      setDurationTimeComboValues();
    }

    public function get durationSecs():Number {
      _durationMilliSecs = getDurationTimeComboValues();
      return _durationSecs;
    }

    [Bindable]
      public function set durationSecs(durationSecs:Number):void {
      _durationSecs = durationSecs;
      _durationMilliSecs
	= _durationSecs * DurationTimeCombo.MILLISECS_PER_SECOND;
      setDurationTimeComboValues();
    }
  }
}